/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ec.socialfun.servicios.externos;

import com.ec.socialfun.entidades.Evento;
import com.ec.socialfun.entidades.Local;
import com.ec.socialfun.entidades.LocalesImagen;
import com.ec.socialfun.entidades.Sucursal;
import com.ec.socialfun.entidades.Usuario;
import com.ec.socialfun.enumeradores.ParametrosEnum;
import com.ec.socialfun.excepciones.CrearArchivoException;
import com.ec.socialfun.excepciones.DescargarArchivoException;
import com.ec.socialfun.excepciones.ParametroException;
import com.ec.socialfun.excepciones.RecuperaLocalesImagenException;
import com.ec.socialfun.servicios.EventoFacade;
import com.ec.socialfun.servicios.LocalesFacade;
import com.ec.socialfun.servicios.LocalesImagenFacade;
import com.ec.socialfun.servicios.ParametrosFacade;
import com.ec.socialfun.servicios.SucursalFacade;
import com.ec.socialfun.servicios.UsuarioFacade;
import com.ec.socialfun.util.Archivo;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.jboss.logging.Logger;

/**
 *
 * @author hp
 */
@Stateless
public class FtpServicio {

    private static final Logger LOG = Logger.getLogger(FtpServicio.class.getName());
    @EJB
    private ParametrosFacade parametrosFacade;
    @EJB
    private UsuarioFacade usuarioFacade;
    @EJB
    private SucursalFacade sucursalFacade;
    @EJB
    private LocalesFacade localesFacade;
    @EJB
    private EventoFacade eventoFacade;
    @EJB
    private LocalesImagenFacade localesImagenFacade;
    private String servidorFtp;
    private String usuarioFtp;
    private String passwordFtp;
    private String rootClienteFtp;
    private String imagenPerfil;
    private String protocoloWeb;
    private String rootLocalFtp;
    private String perfijoCarpetaSuc;
    private String prefijoCarpetaEvento;
    private String prefijoCarpetaImagenesLocal;
    private String prefijoCarpetaProducto;
    private FTPClient ftp;
    private final String caracterEscape = "/";
    private final String cadenaVacia = "";

    @PostConstruct
    public void inciarDatos() {
        try {
            servidorFtp = parametrosFacade.recuperaPorNombre(ParametrosEnum.SERVIDOR_FTP.getNombre()).getPaValor();
            usuarioFtp = parametrosFacade.recuperaPorNombre(ParametrosEnum.USUARIO_FTP.getNombre()).getPaValor();
            passwordFtp = parametrosFacade.recuperaPorNombre(ParametrosEnum.PASS_FTP.getNombre()).getPaValor();
            rootClienteFtp = parametrosFacade.recuperaPorNombre(ParametrosEnum.CARPETA_CLIENTE_FTP.getNombre()).getPaValor();
            imagenPerfil = parametrosFacade.recuperaPorNombre(ParametrosEnum.NOMBRE_IMAGEN_PERFIL.getNombre()).getPaValor();
            protocoloWeb = parametrosFacade.recuperaPorNombre(ParametrosEnum.PROTOCOLO_WEB.getNombre()).getPaValor();
            rootLocalFtp = parametrosFacade.recuperaPorNombre(ParametrosEnum.CARPETA_LOCAL_FTP.getNombre()).getPaValor();
            perfijoCarpetaSuc = parametrosFacade.recuperaPorNombre(ParametrosEnum.PREFIJO_CARPETA_SUCURSAL.getNombre()).getPaValor();
            prefijoCarpetaEvento = parametrosFacade.recuperaPorNombre(ParametrosEnum.PREFIJO_CARPETA_EVEN.getNombre()).getPaValor();
            prefijoCarpetaImagenesLocal = parametrosFacade.recuperaPorNombre(ParametrosEnum.PREFIJO_CARPETA_IMG_LOCAL.getNombre()).getPaValor();
            prefijoCarpetaProducto = parametrosFacade.recuperaPorNombre(ParametrosEnum.PREFIJO_CARPETA_PROD.getNombre()).getPaValor();
            ftp = new FTPClient();
        } catch (ParametroException e) {
            LOG.error(" Error en la recuperacion de parametros " + e);
        }

    }

    /**
     * crea fichero para almacenamiento de imagenes tanto para usuarios tipo
     * CLIENTE
     *
     * @param usuario
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void crearFicheroImagenesUsuarioFtp(Usuario usuario) throws CrearArchivoException {

        try {
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            String ruta = new StringBuilder(rootClienteFtp).append("/").append(usuario.getUsCodigo()).toString();
            if (!ftp.makeDirectory(ruta)) {
                LOG.error("No se ha podido crear el fichero en la ruta: " + ruta);
                throw new CrearArchivoException("No se ha podido crear el fichero");
            }
            ftp.disconnect();
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    /**
     * sube imagen a la carpeta ftp del usuario tipo CLIENTE
     *
     * @param archivo
     * @return
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String subeImagenAFtp(Archivo archivo) throws CrearArchivoException {
        try {
            Usuario usuario = usuarioFacade.recuperarPorCodigo(archivo.getCodigo());
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String ruta = new StringBuilder(rootClienteFtp).append("/").append(usuario.getUsCodigo()).append("/").append(imagenPerfil).toString();
            ftp.storeFile(ruta, archivo.getInputStream());
            ftp.disconnect();
            String rutaCompleta = new StringBuilder(protocoloWeb).append(servidorFtp).append("/").append(ruta).toString();
            usuario.setUsImagen(rutaCompleta);
            usuarioFacade.edit(usuario);
            return rutaCompleta;
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    /**
     * crear el fichero de imagenes para la sucursal, dependiendo del parametro
     * conCarpetaRaiz crea o no la carpeta de locales
     *
     * @param sucursal
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void crearFicheroImagenesSucursalFtp(Sucursal sucursal, boolean conCarpetaRaiz) throws CrearArchivoException {

        try {
            String ruta;
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            if (conCarpetaRaiz) {
                ruta = new StringBuilder(rootLocalFtp).append("/").append(sucursal.getLoCodigo().getLoCodigo()).toString();
                if (!ftp.makeDirectory(ruta)) {
                    LOG.error("No se ha podido crear el fichero en la ruta: " + ruta);
                    throw new CrearArchivoException("No se ha podido crear el fichero");
                }
                // creacion de carpeta para imagenes del local
                ruta = new StringBuilder(rootLocalFtp).append("/").append(sucursal.getLoCodigo().getLoCodigo()).
                        append("/").append(prefijoCarpetaImagenesLocal).toString();
                if (!ftp.makeDirectory(ruta)) {
                    LOG.error("No se ha podido crear el fichero en la ruta: " + ruta);
                    throw new CrearArchivoException("No se ha podido crear el fichero");
                }

            }

            ruta = new StringBuilder(rootLocalFtp).append("/").append(sucursal.getLoCodigo().getLoCodigo()).
                    append("/").append(perfijoCarpetaSuc).append("_").append(sucursal.getSuCodigo()).toString();

            if (!ftp.makeDirectory(ruta)) {
                LOG.error("No se ha podido crear el fichero en la ruta: " + ruta);
                throw new CrearArchivoException("No se ha podido crear el fichero");
            }

            ftp.disconnect();
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    /**
     * sube imagen a la carpeta ftp del usuario tipo Local
     *
     * @param archivo
     * @return
     * @throws CrearArchivoExceptionevento
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String subeImagenSucAFtp(Archivo archivo) throws CrearArchivoException {
        try {
            Sucursal sucursal = sucursalFacade.recuperarPorCodigo(archivo.getCodigo());
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);

            String ruta = new StringBuilder(rootLocalFtp).append("/").append(sucursal.getLoCodigo().getLoCodigo()).
                    append("/").append(perfijoCarpetaSuc).append("_").append(sucursal.getSuCodigo()).append("/").append(imagenPerfil).toString();

            ftp.storeFile(ruta, archivo.getInputStream());
            ftp.disconnect();
            String rutaCompleta = new StringBuilder(protocoloWeb).append(servidorFtp).append("/").append(ruta).toString();
            sucursal.setSuImagen(rutaCompleta);
            sucursalFacade.edit(sucursal);
            return rutaCompleta;

        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    /**
     * sube imagen a la carpeta ftp del usuario tipo Local
     *
     * @param archivo
     * @return
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String subeImagenLocAFtp(Archivo archivo) throws CrearArchivoException {
        try {
            Local local = localesFacade.recuperarPorCodigo(archivo.getCodigo());
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String ruta = new StringBuilder(rootLocalFtp).append("/").append(local.getLoCodigo()).append("/").
                    append(imagenPerfil).toString();
            ftp.storeFile(ruta, archivo.getInputStream());
            ftp.disconnect();
            String rutaCompleta = new StringBuilder(protocoloWeb).append(servidorFtp).append("/").append(ruta).toString();
            local.setLoImagen(rutaCompleta);
            localesFacade.edit(local);
            return rutaCompleta;
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    /**
     * Crea fichero de imagenes para el evento
     *
     * @param evento
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void crearFicheroImagenesEventoFtp(Evento evento) throws CrearArchivoException {

        try {
            String ruta;
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            Local local = sucursalFacade.recuperarPorCodigo(evento.getSuCodigo().getSuCodigo()).getLoCodigo();
            ruta = new StringBuilder(rootLocalFtp).append("/").append(local.getLoCodigo()).
                    append("/").append(perfijoCarpetaSuc).append("_").append(evento.getSuCodigo().getSuCodigo()).append("/").append(prefijoCarpetaEvento).
                    append("_").append(evento.getEvCodigo()).toString();

            if (!ftp.makeDirectory(ruta)) {
                LOG.error("No se ha podido crear el fichero en la ruta: " + ruta);
                throw new CrearArchivoException("No se ha podido crear el fichero");
            }
            ftp.disconnect();
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String subeImagenEventoAFtp(Archivo archivo) throws CrearArchivoException {
        try {
            Evento evento = eventoFacade.recuperaPorCodigo(archivo.getCodigo());
            Local local = sucursalFacade.recuperarPorCodigo(evento.getSuCodigo().getSuCodigo()).getLoCodigo();

            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String ruta = new StringBuilder(rootLocalFtp).append("/").append(local.getLoCodigo()).
                    append("/").append(perfijoCarpetaSuc).append("_").append(evento.getSuCodigo().getSuCodigo()).append("/").append(prefijoCarpetaEvento).
                    append("_").append(evento.getEvCodigo()).append("/").
                    append(imagenPerfil).toString();

            ftp.storeFile(ruta, archivo.getInputStream());
            ftp.disconnect();
            String rutaCompleta = new StringBuilder(protocoloWeb).append(servidorFtp).append("/").append(ruta).toString();

            evento.setEvFoto(rutaCompleta);
            eventoFacade.edit(evento);
            return rutaCompleta;
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }

    /**
     * Sube la imagen de la galeria de fotos del local a la carpeta FTP
     *
     * @param archivo
     * @return
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String subeImagenesLocAFtp(Archivo archivo) throws CrearArchivoException {
        try {
            Local local = localesFacade.recuperarPorCodigo(archivo.getCodigo());
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String ruta = new StringBuilder(rootLocalFtp).append("/").append(local.getLoCodigo()).
                    append("/").append(prefijoCarpetaImagenesLocal).append("/").append("IMAGEN_GALERIA_").append(archivo.getOrden()).toString();
            ftp.storeFile(ruta, archivo.getInputStream());
            ftp.disconnect();
            String rutaCompleta = new StringBuilder(protocoloWeb).append(servidorFtp).append("/").append(ruta).toString();
            LocalesImagen localesImagen = localesImagenFacade.recuperaPorLocalYOrden(local, archivo.getOrden());
            localesImagen.setLoImRutaFoto(rutaCompleta);
            localesImagenFacade.edit(localesImagen);
            return rutaCompleta;

        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        } catch (RecuperaLocalesImagenException e) {
            LOG.error("No se ha podido recuperar la imagen del local: " + e);
            throw new CrearArchivoException("No se ha podido recuperar la imagen del local");
        }
    }

    /**
     * descarga una imagen del servidor FTP
     * @param ruta
     * @return
     * @throws DescargarArchivoException
     */
    public InputStream obtenerImagenDeFTP(String ruta) throws DescargarArchivoException {
        try {
            if (ruta == null || ruta.trim().length() == 0) {
                throw new DescargarArchivoException("Error al descargar la imagen " + ruta + " ruta no especificada");
            }

            ruta = ruta.replaceAll(servidorFtp + caracterEscape, cadenaVacia);
            ruta = ruta.replaceAll(protocoloWeb, cadenaVacia);
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            InputStream iestream = ftp.retrieveFileStream(ruta);
            ftp.disconnect();
            return iestream;
        } catch (IOException e) {
            LOG.error("Error al descargar la imagen " + ruta + " , descripcion del error: " + e);
            throw new DescargarArchivoException("Error al descargar la imagen " + ruta);
        }
    }
    
    /**
     * crear fichero dentro de un local para las imagenes de productos
     * @param local
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void crearFicheroImagenesProductoFtp(Local local) throws CrearArchivoException {

        try {
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            String ruta = new StringBuilder(rootLocalFtp).append("/").append(local.getLoCodigo()).
                        append("/").append(prefijoCarpetaProducto).toString();
            if (!ftp.makeDirectory(ruta)) {
                LOG.error("No se ha podido crear el fichero en la ruta: " + ruta);
                throw new CrearArchivoException("No se ha podido crear el fichero");
            }
            ftp.disconnect();
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }
    
    /**
     * sube imagen de producto al fichero Productos dentro de un local
     * @param archivo
     * @param archivo2
     * @return
     * @throws CrearArchivoException
     */
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public String subeImagenProAFtp(Archivo archivo, Archivo producto) throws CrearArchivoException {
        try {
            Local local = localesFacade.recuperarPorCodigo(archivo.getCodigo());
            ftp.connect(servidorFtp);
            ftp.login(usuarioFtp, passwordFtp);
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            String ruta = new StringBuilder(rootLocalFtp).append("/").append(local.getLoCodigo()).append("/").
                    append(prefijoCarpetaProducto).append("/").append(producto.getCodigo()).toString();
            ftp.storeFile(ruta, archivo.getInputStream());
            ftp.disconnect();
            String rutaCompleta = new StringBuilder(protocoloWeb).append(servidorFtp).append("/").append(ruta).toString();
            return rutaCompleta;
        } catch (IOException e) {
            LOG.error("No se ha podido conectar con el servidor ftp: " + e);
            throw new CrearArchivoException("No se ha podido conectar con el servidor ftp");
        }
    }
    
}
